home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / graphics / mandel18.3 < prev    next >
Text File  |  1989-05-18  |  62KB  |  2,171 lines

  1. Path: xanth!ames!sun-barr!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i144:  mandel - mandelobrot generator v180, Part03/04
  5. Message-ID: <105555@sun.Eng.Sun.COM>
  6. Date: 17 May 89 15:53:40 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 2160
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: u211344@hnykun11.bitnet (Olaf 'Rhialto' Seibert)
  12. Posting-number: Volume 89, Issue 144
  13. Archive-name: graphics/mandel180.3
  14.  
  15. # This is a shell archive.
  16. # Remove anything above and including the cut line.
  17. # Then run the rest of the file through 'sh'.
  18. # Unpacked files will be owned by you and have default permissions.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar: SHell ARchive
  22. # Run the following text through 'sh' to create:
  23. #    Main.c
  24. #    Makefile
  25. #    Mandel.h
  26. #    Menu.c
  27. #    MinRexx.c
  28. #    Misc.c
  29. # This is archive 3 of a 4-part kit.
  30. # This archive created: Wed May 17 20:45:13 1989
  31. echo "extracting Main.c"
  32. sed 's/^X//' << \SHAR_EOF > Main.c
  33. X/*
  34. X * M A N D E L B R O T      C O N S T R U C T I O N   S E T
  35. X *
  36. X * (C) Copyright 1989 by Olaf Seibert.
  37. X * Mandel may be freely distributed. See file 'doc/Notice' for details.
  38. X *
  39. X * Main Loop, and a lot of Variables.
  40. X */
  41. X
  42. X#include <exec/types.h>
  43. X#include <intuition/intuition.h>
  44. X#ifdef DEBUG
  45. X#   include <stdio.h>
  46. X#   undef STATIC
  47. X#   define STATIC        /* EMPTY */
  48. X#endif
  49. X
  50. X#include "mandel.h"
  51. X
  52. Xextern int    Enable_Abort;
  53. X
  54. Xstruct IntuitionBase *IntuitionBase;
  55. Xstruct GfxBase *GfxBase;
  56. Xstruct LayersBase *LayersBase;
  57. X
  58. Xstruct TextAttr Topaz80 = {
  59. X    (STRPTR) "topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT
  60. X};
  61. X
  62. Xstruct TextAttr Topaz60 = {
  63. X    (STRPTR) "topaz.font", TOPAZ_SIXTY, FS_NORMAL, FPF_ROMFONT
  64. X};
  65. X
  66. Xstruct NewScreen MandelNScreen =
  67. X{
  68. X    0, 0, 320, 256,        /* LeftEdge, TopEdge, Width, Height */
  69. X    4,                /* Depth */
  70. X    2, 1,            /* DetailPen, BlockPen */
  71. X    NULL,            /* viewmode LORES */
  72. X    CUSTOMSCREEN,        /* type */
  73. X    &Topaz80,            /* Font (default) */
  74. X#ifdef IEEEDP
  75. X    (UBYTE *) "DP Mandelbrot Construction Set 1.3"
  76. X#else
  77. X    (UBYTE *) "FFP Mandelbrot Construction Set 1.3"
  78. X#endif
  79. X};
  80. X
  81. Xstruct NewWindow MainNWindow =
  82. X{
  83. X    0, 0, 0, 0,         /* LeftEdge, TopEdge, Width, Height */
  84. X    2, 1,            /* DetailPen, BlockPen */
  85. X    CLOSEWINDOW | MENUPICK | MOUSEBUTTONS | VANILLAKEY |
  86. X    SIZEVERIFY /* | MENUVERIFY */ ,
  87. X    WINDOWCLOSE | ACTIVATE | WINDOWSIZING | WINDOWDRAG |
  88. X    WINDOWDEPTH | NOCAREREFRESH | SMART_REFRESH | GIMMEZEROZERO,
  89. X    NULL,            /* FirstGadget */
  90. X    NULL,            /* default CheckMark */
  91. X    (UBYTE *) "Mandelbrot Construction Window", /* Title */
  92. X    NULL,            /* Screen */
  93. X    NULL,            /* BitMap */
  94. X    60, 25,            /* MinWidth, MinHeight */
  95. X    -1, -1,            /* MaxWidth, MaxHeight */
  96. X    CUSTOMSCREEN        /* Screen type */
  97. X};
  98. X
  99. Xstruct BorderInfo borderinfo;
  100. X
  101. Xstruct IntuiText PositiveText = {
  102. X    AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
  103. X    AUTOLEFTEDGE, AUTOTOPEDGE, NULL, (UBYTE *) "Continue", NULL
  104. X},
  105. X
  106. X        NegativeText = {
  107. X    AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
  108. X    AUTOLEFTEDGE, AUTOTOPEDGE, &Topaz60, (UBYTE *) "Cancel", NULL
  109. X};
  110. X
  111. XSTATIC SHORT    XY1[] = {0, 0, 0, 13, 78, 13, 78, 0, 0, 0};
  112. XSTATIC SHORT    XY2[] = {0, 0, 0, 17, 82, 17, 82, 0, 0, 0};
  113. XSTATIC struct Border border[] = {
  114. X    {0, 0, 2, 0, JAM1, 5, XY1, &border[1]},
  115. X    {-2, -2, 3, 0, JAM1, 5, XY2, NULL}
  116. X};
  117. Xstruct Gadget    NegativeGadget = {
  118. X    NULL, -100, -20, 79, 14,    /* next, LTWH */
  119. X    GADGHCOMP | GRELBOTTOM | GRELRIGHT,
  120. X    RELVERIFY | ENDGADGET,
  121. X    BOOLGADGET | REQGADGET,
  122. X    (APTR) & border[0], NULL,
  123. X    &NegativeText, 0, NULL,
  124. X    NEGGADGETID, NULL
  125. X};
  126. Xstruct Gadget    PositiveGadget = {
  127. X    &NegativeGadget, 20, -20, 79, 14,    /* next, LTWH */
  128. X    GADGHCOMP | GRELBOTTOM,
  129. X    RELVERIFY | ENDGADGET,
  130. X    BOOLGADGET | REQGADGET,
  131. X    (APTR) & border[0], NULL,
  132. X    &PositiveText, 0, NULL,
  133. X    POSGADGETID, NULL
  134. X};
  135. X
  136. XUBYTE        PenTable[MAXDEPTH];
  137. Xunsigned    PenTableMode = MODULO;
  138. Xshort        RangeWidth = 2;
  139. X
  140. Xstruct Screen  *MandelScreen = NULL;    /* Pointer for OpenScreen return
  141. X                     * value */
  142. Xstruct Window  *MainWindow = NULL;    /* Idem for OpenWindow */
  143. Xstruct Window  *XYwindow;    /* The X/Y window */
  144. Xextern struct Window *ColorWindow;    /* Palette */
  145. X
  146. X
  147. XUSHORT        WBWidth = 0;    /* Preferred size of our screen */
  148. XUSHORT        WBHeight = 0;    /* in Hires/noninterlace values */
  149. X
  150. Xint        (*DepthFunc) () = ZQuadMinC;
  151. XUBYTE        FunctionNr = 0;
  152. X
  153. Xvoid        (*IPlotFunc) () = None;
  154. XUBYTE        IPlotNr = 0;
  155. X
  156. Xvoid        (*EPlotFunc) () = PlotIterationCount;
  157. XUBYTE        EPlotNr = 0;
  158. X
  159. Xdouble        LeftEdge = -0.800,    /* Left edge of the picture */
  160. X        RightEdge = 2.100,
  161. X        TopEdge = 1.200,
  162. X        BottomEdge = -1.200;
  163. X
  164. Xdouble        CXStep,     /* Stepsize through the complex plane */
  165. X        CYStep;
  166. Xint        PixelStep = 1,    /* Stepsize on the screen */
  167. X        MaxDepth = 100; /* Maximum iteration count */
  168. X
  169. Xint NumColors;            /* Number of colors on the screen */
  170. X
  171. Xunsigned short    FrameX1,
  172. X        FrameX2,
  173. X        FrameY1,
  174. X        FrameY2;
  175. X
  176. Xshort        MouseStatus = NOTFRAMING;    /* Where we are in the
  177. X                         * process of selecting a
  178. X                         * frame */
  179. X
  180. Xbool        finished = FALSE;    /* TRUE to stop the program */
  181. Xbool        Saved = TRUE;    /* Indicates the picture has been SAVEd */
  182. Xbool        NameValid = FALSE;    /* Indicates the file name is
  183. X                     * valid */
  184. Xbool        StillDrawing = FALSE;    /* Are we still drawing ? */
  185. X
  186. XFILE           *BatchFILE;    /* Current batch file */
  187. Xint        DrawSigBit = -1;/* Signal when drawing is finished */
  188. Xlong        DrawSigMask;
  189. X
  190. X#ifdef AREXX
  191. X
  192. X/*
  193. X *  And here is some AREXX stuff. Not very complicated, thanks to
  194. X *  MinRexx by Tomas Rokicki (Radical Eye Software).
  195. X */
  196. X
  197. Xlong        RexxMask;    /* Wait signal mask */
  198. Xextern short    BatchWaiting;    /* Halting all Arexx traffic as well */
  199. X
  200. X#endif
  201. X
  202. X/*
  203. X * M A I N   E N T R Y     P O I N T
  204. X */
  205. X
  206. Xmain(argc, argv)
  207. Xint        argc;
  208. Xchar          **argv;
  209. X{
  210. X    char       *Main();
  211. X    extern struct SignalSemaphore DrawSemaphore;
  212. X
  213. X    /*
  214. X     * Before we do anything, do an operation which requires the floating
  215. X     * point library. So if it is not available, we abort before we need
  216. X     * to clean up anything. Note that CXStep is not initialized at this
  217. X     * moment.
  218. X     */
  219. X
  220. X    CXStep = 1.0;
  221. X    CXStep = CXStep * 2.0;
  222. X
  223. X    /*
  224. X     * Make sure we aren't interrupted by any user pressing ^C while we
  225. X     * are doing I/O.
  226. X     */
  227. X    Enable_Abort = 0;
  228. X
  229. X    /*
  230. X     * Open each of the libraries and check for a NULL return, which
  231. X     * indicates unavailability.
  232. X     */
  233. X
  234. X    IntuitionBase = (struct IntuitionBase *)
  235. X    OpenLibrary("intuition.library", LIBRARY_VERSION);
  236. X    if (IntuitionBase == NULL)
  237. X    MyExit("Can't open Intuition V1.2 or newer!");
  238. X
  239. X    GfxBase = (struct GfxBase *)
  240. X    OpenLibrary("graphics.library", LIBRARY_VERSION);
  241. X    if (GfxBase == NULL)
  242. X    MyExit("Can't open Gfx V1.2 or newer!");
  243. X
  244. X    LayersBase = (struct LayersBase *)
  245. X    OpenLibrary("layers.library", LIBRARY_VERSION);
  246. X    if (LayersBase == NULL)
  247. X    MyExit("Can't open Layers V1.2 or newer!");
  248. X
  249. X    DrawSigBit = AllocSignal(-1L);
  250. X    if (DrawSigBit == -1)
  251. X    MyExit("Can't allocate signal!");
  252. X    DrawSigMask = 1L << DrawSigBit;
  253. X    InitSemaphore(&DrawSemaphore);
  254. X    MandelTask = FindTask(NULL);
  255. X
  256. X#ifdef AREXX
  257. X/*
  258. X *   For rexx, we open up a Rexx port, and Batch() will send out
  259. X *   the first command, if there was one.
  260. X */
  261. X    RexxMask = upRexxPort("MANDEL", NULL, "mand", NULL) ;
  262. X#endif
  263. X    if (InitDisplay((bool) FALSE))
  264. X    MyExit("Can't initialise the display properly!");
  265. X
  266. X    CalcCSteps();
  267. X    Options(argc, argv);        /* Maybe open the batch */
  268. X    Batch();                    /* Check the batch */
  269. X
  270. X    MyExit(Main());
  271. X}
  272. X
  273. Xchar           *
  274. XMain()
  275. X{
  276. X    register ULONG  Class;    /* IntuiMessage class */
  277. X    register USHORT Code;    /* and Code field */
  278. X    struct IntuiMessage *message;    /* Expected message pointer */
  279. X    struct Window  *window;    /* window related to message */
  280. X    long        signalmask;
  281. X    long        signals;
  282. X
  283. X#ifdef AREXX
  284. X/*
  285. X *   If we're working with Rexx, we wait on the Rexx bit as well.
  286. X *   Then, we handle any Rexx messages.
  287. X */
  288. X    signalmask = RexxMask | DrawSigMask |
  289. X           (1L << MainWindow->UserPort->mp_SigBit);
  290. X#else
  291. X    signalmask = DrawSigMask | (1L << MainWindow->UserPort->mp_SigBit);
  292. X#endif
  293. X
  294. Xagain:
  295. X    finished = FALSE;
  296. X    while (!finished) {
  297. X    /*
  298. X     * Wait for message port to become not empty, and extract the
  299. X     * message or, alternatively, for the drawing to finish.
  300. X     */
  301. X
  302. X    signals = Wait(signalmask);
  303. X#ifdef AREXX
  304. X    if ((signals & RexxMask) && !BatchWaiting) {
  305. X        dispRexxPort();
  306. X    }
  307. X#endif
  308. X    if (signals & DrawSigMask) {    /* drawing finished */
  309. X        Batch();                    /* Check the batch */
  310. X#ifdef AREXX
  311. X        Signal(MandelTask, RexxMask);/* Wake up Arexx as well */
  312. X#endif
  313. X    }
  314. X    while (message = (struct IntuiMessage *)
  315. X           GetMsg(MainWindow->UserPort)) {
  316. X        window = message->IDCMPWindow;
  317. X
  318. X        if (window == ColorWindow) {
  319. X        HandleColorWindow(message);
  320. X        continue;
  321. X        }
  322. X
  323. X        Class = message->Class;
  324. X        Code = message->Code;
  325. X
  326. X        if (Class & ~(MOUSEBUTTONS | INTUITICKS)) {
  327. X        ReplyMsg(message);      /* Pointer is not valid anymore */
  328. X        }
  329. X        switch (Class) {
  330. X        case MENUPICK:
  331. X        GotMenu(Code);
  332. X        break;
  333. X        case MOUSEBUTTONS:
  334. X        case INTUITICKS:
  335. X        CheckMouse(message);
  336. X        ReplyMsg(message);
  337. X        break;
  338. X        case SIZEVERIFY:
  339. X        StopFraming();  /* Fall Through to MenuVerify */
  340. X        case MENUVERIFY:
  341. X        break;        /* Just make sure there is no half-drawn
  342. X                 * frame */
  343. X        case CLOSEWINDOW:
  344. X        if (window == MainWindow) {
  345. X            finished = TRUE;
  346. X        } else {
  347. X            CloseXYwindow();
  348. X        }
  349. X        break;
  350. X        case VANILLAKEY:
  351. X        if (Code == ('Q' & 0x1F)) {     /* Ctrl-Q; don't check to
  352. X                         * be sure */
  353. X            skipto        finished;
  354. X        }
  355. X        break;
  356. X        /* default: Ignore strange messages */
  357. X        }            /* End Switch The Class Of The Message */
  358. X    }            /* End While There Is A Message */
  359. X    }                /* End While Not Finished */
  360. X
  361. X    /*
  362. X     * So we are finished. And, by the way, are we SURE we are finished
  363. X     * alltogether ??
  364. X     */
  365. X
  366. X    if (!Sure()) {
  367. X    backto        again;
  368. X    }
  369. Xfinished:
  370. X    CleanupDisplay((bool) TRUE);
  371. X    return NULL;        /* Indicate Good Exit */
  372. X}                /* End of Main */
  373. SHAR_EOF
  374. echo "extracting Makefile"
  375. sed 's/^X//' << \SHAR_EOF > Makefile
  376. X#
  377. X#    Makefile for the Mandelbrot Construction Set by Olaf Seibert, KosmoSoft
  378. X#
  379. X
  380. XSPOBJ    = Main.o Misc.o GotMenu.o Batch.o \
  381. X      Palette.o Draw.o
  382. XDPOBJ    = Main.odp Misc.odp GotMenu.odp Batch.odp \
  383. X      Palette.odp Draw.odp
  384. XINTOBJ    = Display.o Select.o GetFile.o Jiff.o Menu.o Rev.o
  385. XREXXOBJ = MinRexx.o RexxBind.o
  386. XHEADERS = Mandel.h
  387. XLIBS    = -lm -lc
  388. XDPLIBS    = -lma -lc
  389. XDUMP    = ii
  390. XCFLAGS    = +I$(DUMP) +x3,5 -DAREXX
  391. XCC    = cc
  392. X
  393. X.SUFFIXES:
  394. X
  395. X.SUFFIXES:  .odp .o .asm .c .req
  396. X
  397. X.c.odp:
  398. X    $(CC) $(CFLAGS) +fi -DIEEEDP $< -o $@
  399. X
  400. X.c.o:
  401. X    $(CC) $(CFLAGS) $< -o $@
  402. X
  403. X.c.asm:
  404. X    $(CC) $(CFLAGS) -at $< -o $@
  405. X
  406. XDebug:    $(SPOBJ) $(INTOBJ) $(REXXOBJ) $(DUMP)
  407. X    air
  408. X    ln -o Debug -w $(INTOBJ) $(REXXOBJ) $(SPOBJ) $(LIBS)
  409. X
  410. XMandel: $(SPOBJ) $(INTOBJ) $(DUMP)
  411. X    air
  412. X    ln -o Mandel $(INTOBJ) $(REXXOBJ) $(SPOBJ) $(LIBS)
  413. X
  414. XMandel-dp: $(DPOBJ) $(INTOBJ) $(DUMP)
  415. X#    No IncRev so the number is the same as the FFP version
  416. X    ln -o Mandel-dp $(INTOBJ) $(REXXOBJ) $(DPOBJ) $(DPLIBS)
  417. X
  418. Xall:    Mandel Mandel-dp
  419. X
  420. X$(INTOBJ):  $(HEADERS)
  421. X$(SPOBJ):   $(HEADERS)
  422. X$(DPOBJ):   $(HEADERS)
  423. X
  424. XSelect.o:   Select.req
  425. X
  426. XSelect.req: Select.blk
  427. X        blk -d $? $@
  428. X
  429. XMinRexx.o:  MinRexx.h
  430. X
  431. X$(DUMP):    dummy.c
  432. X    cc -a +H$(DUMP) dummy.c -o nil:
  433. SHAR_EOF
  434. echo "extracting Mandel.h"
  435. sed 's/^X//' << \SHAR_EOF > Mandel.h
  436. X/*
  437. X * :ts=8 Common DEFINEs and external declarations for the Mandelbrot
  438. X * Construction Set...
  439. X */
  440. X
  441. X#undef LIBRARY_VERSION
  442. X#define LIBRARY_VERSION     33L /* V1.2 */
  443. X
  444. X
  445. X#define MYFRONTPEN  2        /* Black */
  446. X
  447. X/* Menus */
  448. X#define CPRMENU     0        /* Copyright Menu */
  449. X#define PRJMENU     1        /* Poject Menu */
  450. X#define OPTMENU     2        /* Option Menu */
  451. X#define DRWMENU     3        /* Draw functions Menu */
  452. X#define BATMENU     4        /* Batch Menu */
  453. X
  454. X/* Menu items */
  455. X#define PRJNEW        0        /* Project Menu: New */
  456. X#define PRJOPN        1        /* Open */
  457. X#define PRJSVE        2        /* Save */
  458. X#define PRJSVA        3        /* Save As */
  459. X#define PRJSTP        4        /* Stop */
  460. X#define PRJQUI        5        /* Quit */
  461. X
  462. X#define PNABS        0        /* Project New: Absolute */
  463. X#define PNENL        1        /* Enlarge */
  464. X#define PNRED        2        /* Reduce */
  465. X#define PNSHF        3        /* Shift */
  466. X#define PNZI        4        /* Zoom In */
  467. X#define PNZO        5        /* Zoom Out */
  468. X
  469. X#define OPTCOL        0        /* Option Menu: Colors */
  470. X#define OPTRES        1        /* Resolution */
  471. X#define OPTPAR        2        /* Parameters */
  472. X#define OPTPRI        3        /* Priority */
  473. X
  474. X#define OCSEL        0        /* Opt Color: Select */
  475. X#define OCMOD        1        /* Modulo */
  476. X#define OCRAN        2        /* Ranges */
  477. X#define OCPAL        3        /* Palette */
  478. X
  479. X#define ORNRM        0        /* Opt Resl: Normal */
  480. X#define OR12        1        /* 1/2 */
  481. X#define OR13        2        /* 1/3 */
  482. X#define OR14        3        /* 1/4 */
  483. X#define ORFIL        4        /* Fill In */
  484. X#define ORHI        5        /* HiRes */
  485. X#define ORILC        6        /* Interlace */
  486. X#define ORBCK        7        /* Borderless */
  487. X#define OREHB        8        /* Extra Half Brite */
  488. X
  489. X#define OPNOR        0        /* Normal priority */
  490. X#define OPLOW        1        /* Low priority */
  491. X
  492. X#define DRWFUN        0        /* Draw functions */
  493. X#define DRWIPL        1        /* - Iteration plot */
  494. X#define DRWEPL        2        /* - End plot */
  495. X
  496. X#define DF1        0        /* Functions Menu: Z^2-C */
  497. X#define DF2        1        /* ZC1MinZ */
  498. X#define DF3        2        /* Z3PlusZCMin1MinC */
  499. X#define DFUPF        3        /* Not on the menu for now */
  500. X#define DF5        4        /* i:Z^2 - C */
  501. X
  502. X#define DINONE        0        /* draw iplot none */
  503. X#define DIZ        1        /* iplot Z */
  504. X
  505. X#define DEDEPTH     0        /* draw eplot depth */
  506. X#define DEZ        1        /* eplot Z */
  507. X
  508. X#define BATFILE     0        /* Batch Menu: File... */
  509. X#define BATWAIT     1        /* Wait */
  510. X#define BATCONT     2        /* Continue */
  511. X#define BATABORT    3        /* Abort */
  512. X
  513. X
  514. X#define POSGADGETID 10        /* For Positive Gadget */
  515. X#define NEGGADGETID 11        /* For Negative Gadget */
  516. X
  517. X#define FNAME_SIZE  32L     /* Filename size */
  518. X#define DNAME_SIZE  66L     /* Directoryname size */
  519. X
  520. X#define MAXDEPTH    512     /* Maximum maximum depth */
  521. X#define BMDEPTH     5        /* Depth of our bitmap */
  522. X#define MAXCOL (1<<BMDEPTH)     /* Maximum number of colors */
  523. X
  524. X#define NOTFRAMING  0        /* We are not framing */
  525. X#define NOPOINT     1        /* We have no points of a frame */
  526. X#define POINT1        2        /* We have 1 point of a frame */
  527. X#define CENTERFRAMING 3     /* We have a center and are busy with a
  528. X                 * corner */
  529. X#define FLASHING    4        /* We are still flashing the frame */
  530. X
  531. X#define MODULO        0        /* Pen assignment to the depths */
  532. X#define RANGES        1
  533. X#define SELECT        2
  534. X
  535. X#define MAND        ((ULONG)'M'<<24 | (ULONG)'A'<<16 | 'N'<<8 | 'D')
  536. X
  537. X#define MINSCREENHEIGHT 150    /* Minimum required screen sizes */
  538. X#define MINSCREENWIDTH    320
  539. X
  540. X/* Let's try to make `goto' a little more structured... :-) */
  541. X
  542. X#define skipto        goto
  543. X#define backto        goto
  544. X
  545. X#define OFFSETOF(member, structure) ((long) &((struct structure *)0)->member)
  546. X
  547. X/* Type definitions */
  548. X
  549. Xtypedef short bool;
  550. X
  551. Xstruct BitMapHeader {
  552. X    UWORD        w,
  553. X            h;
  554. X    UWORD        x,
  555. X            y;
  556. X    UBYTE        nPlanes;
  557. X    UBYTE        masking;
  558. X    UBYTE        compression;
  559. X    UBYTE        pad1;
  560. X    UWORD        transparentColor;
  561. X    UBYTE        xAspect,
  562. X            yAspect;
  563. X    WORD        pageWidth,
  564. X            pageHeight;
  565. X};
  566. X
  567. X/*
  568. X * ILBM_info is the structure read_iff returns, and is hopefully all you
  569. X * need to deal with out of the iff reader routines below
  570. X */
  571. Xstruct ILBM_info {
  572. X    struct BitMapHeader header;
  573. X    UBYTE        cmap[MAXCOL * 3];
  574. X    struct BitMap   bitmap;
  575. X    struct Mand    *mand;
  576. X    long        mandsize;
  577. X};
  578. X
  579. Xstruct Mand {
  580. X    ULONG        MandID;    /* 'MAND' */
  581. X    LONG        Size;    /* sizeof(struct Mand) */
  582. X    WORD        MaxDepth;    /* Maximum iteration count */
  583. X    WORD        RangeWidth;
  584. X    BYTE        RainDist;    /* From the palette Rainbow mode */
  585. X    BYTE        RainRMax;    /* From the palette Rainbow mode */
  586. X    BYTE        RainGMax;    /* From the palette Rainbow mode */
  587. X    BYTE        RainBMax;    /* From the palette Rainbow mode */
  588. X    BYTE        Coords[4 * 18];    /* Ascii representation */
  589. X    BYTE        FunctionNr; /* Which function was used (1...4) */
  590. X    BYTE        PenTableMode;    /* MODULO, RANGES, SELECT */
  591. X    USHORT        WBWidth;
  592. X    USHORT        WBHeight;
  593. X};
  594. X
  595. Xstruct BorderInfo {
  596. X    BYTE        SizeX,
  597. X            SizeY;
  598. X    BYTE        MoveX,
  599. X            MoveY;
  600. X};
  601. X
  602. X/* Some definitions for the User Programmed Functions */
  603. X
  604. Xstruct Program {
  605. X    char        pr_OpCode;
  606. X    char        pr_Dest;
  607. X    char        pr_Op1;
  608. X    char        pr_Op2;
  609. X    long        pr__Reserved;
  610. X};
  611. X
  612. Xenum Opcode {
  613. X    End, Rassign, Cassign, Ri, Ci, Rplus, Cplus, Rminus, Cminus,
  614. X    Rtimes, Ctimes,
  615. X};
  616. X
  617. X#define PROGRAMSIZE    64
  618. X#define PROGRAMREGS    16
  619. X
  620. Xextern struct Program Program[PROGRAMSIZE];
  621. Xextern double    PrgReg[2 * PROGRAMREGS];
  622. X
  623. X#define RE(x)           (x)     /* These RE and IM cannot */
  624. X#define IM(x)           ((x) + PROGRAMREGS)     /* be exchanged! */
  625. X
  626. X/* Some Other Macros */
  627. X
  628. X#define MENU(menu,item,subitem)\
  629. X    (LONG)(SHIFTMENU(menu)|SHIFTITEM(item)|SHIFTSUB(subitem))
  630. X
  631. X/* External declarations */
  632. X
  633. X#include <functions.h>
  634. Xextern long    GetScreenData();
  635. X
  636. X/*
  637. X * extern struct Screen *OpenScreen(); extern struct Window *OpenWindow();
  638. X * extern struct IntuiMessage *GetMsg(); extern struct Library
  639. X * *OpenLibrary(); extern struct MenuItem *ItemAddress(); extern long
  640. X * AutoRequest(), DisplayAlert(), Request(), MoveLayer(), SizeLayer();
  641. X * extern void SetAPen(), WritePixel(), WindowLimits(), EndRequest();
  642. X * extern struct Task *FindTask(); extern long Wait();
  643. X */
  644. X
  645. X
  646. X/* Forward POINTER declarations */
  647. X
  648. Xextern struct Screen *MandelScreen;
  649. Xextern struct Window *MainWindow;
  650. Xextern struct IntuiMessage *message;
  651. Xextern int    (*DepthFunc) ();
  652. Xextern void    (*IPlotFunc) ();
  653. Xextern void    (*EPlotFunc) ();
  654. Xextern struct IntuitionBase *IntuitionBase;
  655. Xextern struct LayersBase *LayersBase;
  656. Xextern struct GfxBase *GfxBase;
  657. Xextern FILE    *BatchFILE;
  658. Xextern struct Task *MandelTask,
  659. X           *DrawTask;
  660. X
  661. X
  662. X/* Forward STRUCT declarations */
  663. X
  664. Xextern struct Menu MandelMenu[];
  665. Xextern struct NewScreen MandelNScreen;
  666. Xextern struct NewWindow MainNWindow;
  667. Xextern struct TextAttr Topaz60,
  668. X        Topaz80;
  669. Xextern struct IntuiText PositiveText,
  670. X        NegativeText;
  671. Xextern struct Gadget PositiveGadget,
  672. X        NegativeGadget;
  673. Xextern struct BorderInfo borderinfo;
  674. X
  675. X
  676. X/* Forward ARRAY declarations */
  677. X
  678. Xextern TEXT    FileName[FNAME_SIZE + 1];
  679. Xextern TEXT    DirName[DNAME_SIZE + 2];
  680. X
  681. X
  682. X/* Forward `SIMPLE' declarations */
  683. X
  684. Xextern int    NumColors,
  685. X        MaxDepth,
  686. X        PixelStep,
  687. X        RangeWidth;
  688. Xextern int    DrawPri;
  689. Xextern unsigned PenTableMode;
  690. Xextern unsigned short FrameX1,
  691. X        FrameX2,
  692. X        FrameY1,
  693. X        FrameY2;
  694. Xextern short    MouseStatus;
  695. Xextern bool    finished,
  696. X        StillDrawing,
  697. X        Saved,
  698. X        NameValid;
  699. Xextern double    LeftEdge,
  700. X        RightEdge,
  701. X        TopEdge,
  702. X        BottomEdge,
  703. X        CXStep,
  704. X        CYStep;
  705. Xextern UBYTE    PenTable[MAXDEPTH];
  706. Xextern UBYTE    FunctionNr;
  707. X
  708. Xextern SHORT    RainbowDistance,
  709. X        RainbowRMax,
  710. X        RainbowGMax,
  711. X        RainbowBMax;
  712. Xextern long    DrawSigMask;
  713. Xextern int    DrawSigBit;
  714. Xextern USHORT    WBWidth,
  715. X        WBHeight;
  716. X
  717. X
  718. X/* Forward FUNCTION declarations */
  719. X
  720. Xextern bool    InitDisplay();
  721. Xextern bool    ReInitDisplay();
  722. Xextern bool    Sure();
  723. Xextern bool    CleanupDisplay();
  724. Xextern bool    InterpretMAND();
  725. Xextern bool    DoBorderless();
  726. Xextern bool    DrawPicture();
  727. Xextern bool    OpenAs();
  728. Xextern bool    SaveAs();
  729. Xextern bool    OpenBatch();
  730. X
  731. Xextern int    WaitMyRequest();
  732. Xextern int    write_iff();
  733. Xextern int    ZQuadMinC();
  734. Xextern int    ZC1MinZ();
  735. Xextern int    Z3PlusZCMin1MinC();
  736. Xextern int    UserProgFunc();
  737. Xextern int    I_ZQuadMinC();
  738. X
  739. Xextern float    Ratio();
  740. Xextern char    *get_fname();
  741. Xextern char    *index();
  742. Xextern struct ILBM_info *win_read_iff();
  743. Xextern struct Window *MyRequest();
  744. X
  745. Xextern void    MyExit();
  746. Xextern void    GotMenu();
  747. Xextern void    UndoBorderless();
  748. Xextern void    CprMenu();
  749. Xextern void    PrjMenu();
  750. Xextern void    EdtMenu();
  751. Xextern void    OptMenu();
  752. Xextern void    DrwMenu();
  753. Xextern void    BatchMenu();
  754. Xextern void    UnImpl();
  755. Xextern void    EndMyRequest();
  756. Xextern void    CloseWindowSafely();
  757. Xextern void    get_ea_cmap();
  758. Xextern void    put_ea_cmap();
  759. Xextern void    free_planes();
  760. Xextern void    RectDraw();
  761. Xextern void    CrossDraw();
  762. Xextern void    CheckMouse();
  763. Xextern void    InitPenTable();
  764. Xextern void    StopFraming();
  765. Xextern void    EnableSystemGadgets();
  766. Xextern void    DisableSystemGadgets();
  767. Xextern void    Parameters();
  768. Xextern void    Palette();
  769. Xextern void    MakeMAND();
  770. Xextern void    StopDrawing();
  771. Xextern void    CalcCSteps();
  772. Xextern void    None();
  773. Xextern void    PlotZ();
  774. Xextern void    PlotIterationCount();
  775. Xextern void    SelectMenu();
  776. Xextern void    SuspendDrawing();
  777. Xextern void    ResumeDrawing();
  778. Xextern void    UpdateCheckmarks();
  779. Xextern void    UpdateDrwFunCm();
  780. Xextern void    UpdateDrwIplotCm();
  781. Xextern void    UpdateDrwEplotCm();
  782. Xextern void    UpdateOptColorCm();
  783. Xextern void    UpdateOptDrawResCm();
  784. Xextern void    UpdateOptViewResCm();
  785. Xextern void    UpdateOptPriCm();
  786. Xextern void    CloseBatch();
  787. X
  788. X#ifdef AREXX
  789. X/*
  790. X *   This is the list of functions we can access.  (Cheap forward
  791. X *   declarations, too.)
  792. X */
  793. Xextern long upRexxPort() ;
  794. Xextern void dnRexxPort() ;
  795. Xextern void dispRexxPort() ;
  796. Xextern struct RexxMsg *sendRexxCmd() ;
  797. Xextern struct RexxMsg *syncRexxCmd() ;
  798. Xextern struct RexxMsg *asyncRexxCmd() ;
  799. Xextern void replyRexxCmd() ;
  800. X
  801. Xextern long RexxMask;
  802. X#endif
  803. X
  804. SHAR_EOF
  805. echo "extracting Menu.c"
  806. sed 's/^X//' << \SHAR_EOF > Menu.c
  807. X/*
  808. X * M A N D E L B R O T      C O N S T R U C T I O N   S E T
  809. X *
  810. X * (C) Copyright 1989 by Olaf Seibert.
  811. X * Mandel may be freely distributed. See file 'doc/Notice' for details.
  812. X *
  813. X * Menu definitions.
  814. X */
  815. X
  816. X#include <exec/types.h>
  817. X#include <intuition/intuition.h>
  818. X
  819. X#define MENUFRONTPEN 2
  820. X
  821. X/*-
  822. X * (C)             project     options         draw        batch
  823. X * ----------------------------------------------------------------
  824. X * About Mandel... new *       colors *        function    file...
  825. X *           open... /O  resolution *    iplot       wait
  826. X *           save    /S  parameters      eplot       continue
  827. X *           save as...  priority *           abort
  828. X *           stop
  829. X *           quit    /Q
  830. X *
  831. X * new              colors      resolution     priority
  832. X * -------------------------------------------------------------
  833. X * absolute pos'n /A  select      normal     /1  normal /0
  834. X * enlarge      /E  modulo      1/2         /2  low    /-
  835. X * reduce      /R  ranges      1/3         /3
  836. X * shift      /T  palette /P  1/4         /4
  837. X * zoom in      /<          fill in    /F
  838. X * zoom out      />          hi-res     /H
  839. X *                  interlace  /I
  840. X *                  borderless /B
  841. X *                  halfbrite  //
  842. X *
  843. X * functions       iplot    eplot
  844. X * -------------------------------------------------------------------
  845. X * z^2-c       None     Depth
  846. X * z*c*(1-z)       Z        Z
  847. X * z^3+z*(c-1)-c
  848. X * i:user
  849. X * i:z^2-c
  850. X */
  851. X
  852. X/*
  853. X * Define some handy shortcuts.
  854. X */
  855. X
  856. X#define ITEXT(left,text) \
  857. X    {  MENUFRONTPEN,AUTOBACKPEN,JAM1,left,1,NULL, (UBYTE*)text, NULL  }
  858. X
  859. X#define ITEM(num,top,next,text,flags,mutex,cmd) \
  860. X        SITEM(num,top,next,text,flags,mutex,cmd,NULL)
  861. X
  862. X#define SITEM(num,top,next,text,flags,mutex,cmd,sub) \
  863. X   {next,MLEFT,top,MWIDTH,10,flags,mutex,(APTR)&text[num],NULL,cmd,sub}
  864. X
  865. X#define Ax    COMMSEQ
  866. X#define Vx    CHECKIT
  867. X#define VV    CHECKIT | CHECKED
  868. X#define TG    MENUTOGGLE
  869. X#define EN    ITEMENABLED
  870. X
  871. X#define DEFMLEFT    40
  872. X
  873. X/*
  874. X * First the menu texts.
  875. X */
  876. X
  877. Xstruct IntuiText c_it[] = {
  878. X    ITEXT(1, "About Mandel..."),
  879. X};
  880. X
  881. Xstruct IntuiText project_it[] = {
  882. X    ITEXT(1, "New        \xBB"),    /* 0xBB is the >> character */
  883. X    ITEXT(1, "Open..."),
  884. X    ITEXT(1, "Save"),
  885. X    ITEXT(1, "Save As..."),
  886. X    ITEXT(1, "Stop"),
  887. X    ITEXT(1, "Quit..."),
  888. X};
  889. X
  890. Xstruct IntuiText opts_it[] = {
  891. X    ITEXT(1, "Colors     \xBB"),
  892. X    ITEXT(1, "Resolution \xBB"),
  893. X    ITEXT(1, "Parameters"),
  894. X    ITEXT(1, "Priority   \xBB"),
  895. X};
  896. X
  897. Xstruct IntuiText draw_it[] = {
  898. X    ITEXT(1, "Func  \xBB"),
  899. X    ITEXT(1, "IPlot \xBB"),
  900. X    ITEXT(1, "EPlot \xBB"),
  901. X};
  902. X
  903. Xstruct IntuiText batch_it[] = {
  904. X    ITEXT(1, "File..."),
  905. X    ITEXT(1, "Wait"),
  906. X    ITEXT(1, "Continue"),
  907. X    ITEXT(1, "Abort"),
  908. X};
  909. X
  910. Xstruct IntuiText new_it[] = {
  911. X    ITEXT(1, "Absolute"),
  912. X    ITEXT(1, "Enlarge"),
  913. X    ITEXT(1, "Reduce"),
  914. X    ITEXT(1, "Shift"),
  915. X    ITEXT(1, "Zoom In"),
  916. X    ITEXT(1, "Zoom Out"),
  917. X};
  918. X
  919. Xstruct IntuiText color_it[] = {
  920. X    ITEXT(CHECKWIDTH, "Select"),
  921. X    ITEXT(CHECKWIDTH, "Modulo"),
  922. X    ITEXT(CHECKWIDTH, "Ranges"),
  923. X    ITEXT(CHECKWIDTH, "Palette"),
  924. X};
  925. X
  926. Xstruct IntuiText pri_it[] = {
  927. X    ITEXT(CHECKWIDTH, "Normal"),
  928. X    ITEXT(CHECKWIDTH, "Low"),
  929. X};
  930. X
  931. Xstruct IntuiText res_it[] = {
  932. X    ITEXT(CHECKWIDTH, "Normal"),
  933. X    ITEXT(CHECKWIDTH, "1/2"),
  934. X    ITEXT(CHECKWIDTH, "1/3"),
  935. X    ITEXT(CHECKWIDTH, "1/4"),
  936. X    ITEXT(CHECKWIDTH, "Fill In"),
  937. X    ITEXT(CHECKWIDTH, "Hires"),
  938. X    ITEXT(CHECKWIDTH, "Interlace"),
  939. X    ITEXT(CHECKWIDTH, "BorderLess"),
  940. X    ITEXT(CHECKWIDTH, "HalfBrite"),
  941. X};
  942. X
  943. Xstruct IntuiText fun_it[] = {
  944. X    ITEXT(CHECKWIDTH, "Z^2-C"),
  945. X    ITEXT(CHECKWIDTH, "Z*C*(1-Z)"),
  946. X    ITEXT(CHECKWIDTH, "Z^3+Z*(C-1)-C"),
  947. X    ITEXT(CHECKWIDTH, "iplot: User"),
  948. X    ITEXT(CHECKWIDTH, "iplot: Z^2-C"),
  949. X};
  950. X
  951. Xstruct IntuiText plot_it[] = {
  952. X    ITEXT(CHECKWIDTH, "None"),
  953. X    ITEXT(CHECKWIDTH, "Depth"),
  954. X    ITEXT(CHECKWIDTH, "Z"),
  955. X};
  956. X
  957. X
  958. X#define FLAGS    ITEMTEXT | ITEMENABLED | HIGHBOX
  959. X
  960. X/*
  961. X *  New submenu
  962. X */
  963. X
  964. X#define MLEFT    DEFMLEFT
  965. X#define MWIDTH    8*8+2+COMMWIDTH+8   /* Funny we need 2 more pixels */
  966. X
  967. Xstruct MenuItem new_mi[] = {
  968. X    ITEM(0,05,&new_mi[1],new_it,FLAGS|Ax,0,'A'), /* absolute */
  969. X    ITEM(1,15,&new_mi[2],new_it,FLAGS|Ax,0,'E'), /* enlarge */
  970. X    ITEM(2,25,&new_mi[3],new_it,FLAGS|Ax,0,'R'), /* reduce */
  971. X    ITEM(3,35,&new_mi[4],new_it,FLAGS|Ax,0,'T'), /* shift */
  972. X    ITEM(4,45,&new_mi[5],new_it,FLAGS|Ax,0,'<'), /* Zoom In */
  973. X    ITEM(5,55,NULL,      new_it,FLAGS|Ax,0,'>'), /* Zoom Out */
  974. X};
  975. X
  976. X/*
  977. X *  Colors submenu
  978. X */
  979. X
  980. X#undef    MWIDTH
  981. X#define MWIDTH    CHECKWIDTH+7*8+COMMWIDTH+8
  982. X
  983. Xstruct MenuItem color_mi[] = {
  984. X    ITEM(0,05,&color_mi[1],color_it,FLAGS|Vx,1<<1|1<<2,0), /* select */
  985. X    ITEM(1,15,&color_mi[2],color_it,FLAGS|VV,1<<0|1<<2,0), /* modulo */
  986. X    ITEM(2,25,&color_mi[3],color_it,FLAGS|Vx,1<<0|1<<1,0), /* ranges */
  987. X    ITEM(3,35,NULL        ,color_it,FLAGS|Ax,0,      'P'), /* palette */
  988. X};
  989. X
  990. X#undef    MWIDTH
  991. X#define MWIDTH CHECKWIDTH+10*8+COMMWIDTH+8
  992. X
  993. Xstruct MenuItem res_mi[] = {
  994. X    ITEM(0,05,&res_mi[1],res_it,FLAGS|Ax|VV,1<<1|1<<2|1<<3,'1'), /* normal */
  995. X    ITEM(1,15,&res_mi[2],res_it,FLAGS|Ax|Vx,1<<0|1<<2|1<<3,'2'), /* 1/2 */
  996. X    ITEM(2,25,&res_mi[3],res_it,FLAGS|Ax|Vx,1<<0|1<<1|1<<3,'3'), /* 1/3 */
  997. X    ITEM(3,35,&res_mi[4],res_it,FLAGS|Ax|Vx,1<<0|1<<1|1<<2,'4'), /* 1/4 */
  998. X    ITEM(4,45,&res_mi[5],res_it,FLAGS|Ax   ,0             ,'F'), /* fill in */
  999. X
  1000. X    ITEM(5,60,&res_mi[6],res_it,FLAGS|Ax|Vx|TG,1<<8,'H'),   /* hi-res */
  1001. X    ITEM(6,70,&res_mi[7],res_it,FLAGS|Ax|Vx|TG,0   ,'I'),   /* interlace */
  1002. X    ITEM(7,80,&res_mi[8],res_it,FLAGS|Ax|Vx|TG,0   ,'B'),   /* borderless */
  1003. X    ITEM(8,90,NULL      ,res_it,FLAGS|Ax|Vx|TG,1<<4,'/'),   /* extra halfbrite */
  1004. X};
  1005. X
  1006. X#undef    MWIDTH
  1007. X#define MWIDTH CHECKWIDTH+6*8+COMMWIDTH+8
  1008. X
  1009. Xstruct MenuItem pri_mi[] = {
  1010. X    ITEM(0,05,&pri_mi[1],pri_it,FLAGS|Ax|VV,1<<1,'0'), /* normal */
  1011. X    ITEM(1,15,NULL      ,pri_it,FLAGS|Ax|Vx,1<<0,'-'), /* low */
  1012. X};
  1013. X
  1014. X/*
  1015. X *  Functions submenu:
  1016. X */
  1017. X
  1018. X#undef    MWIDTH
  1019. X#define MWIDTH    CHECKWIDTH+104
  1020. X#undef    MLEFT
  1021. X#define MLEFT    DEFMLEFT - 8
  1022. X
  1023. Xstruct MenuItem fun_mi[] = {
  1024. X    ITEM(0,05,&fun_mi[1],fun_it,FLAGS|VV,0x1F- 1,0), /* Z^2 - C */
  1025. X    ITEM(1,15,&fun_mi[2],fun_it,FLAGS|Vx,0x1F- 2,0), /* z*c*(1-z) */
  1026. X    ITEM(2,25,&fun_mi[3],fun_it,FLAGS|Vx,0x1F- 4,0), /* z^3+z*(c-1)-c */
  1027. X    ITEM(3,35,&fun_mi[4],fun_it,FLAGS|Vx,0x1F- 8,0), /* i: User */
  1028. X    ITEM(4,45,NULL      ,fun_it,FLAGS|Vx,0x1F-16,0), /* i: Z^2 - C */
  1029. X};
  1030. X
  1031. X/*
  1032. X *  iplot submenu
  1033. X */
  1034. X
  1035. X#undef    MWIDTH
  1036. X#define MWIDTH    CHECKWIDTH + (5*8)
  1037. X#undef    MLEFT
  1038. X#define MLEFT    DEFMLEFT
  1039. X
  1040. Xstruct MenuItem iplot_mi[] = {
  1041. X    ITEM(0,05,&iplot_mi[1],  plot_it,  FLAGS|VV,1<<1,0), /* None */
  1042. X    ITEM(1,15,NULL        ,(plot_it+1),FLAGS|Vx,1<<0,0), /* Z */
  1043. X};
  1044. X
  1045. X/*
  1046. X *  eplot submenu
  1047. X */
  1048. X
  1049. Xstruct MenuItem eplot_mi[] = {
  1050. X    ITEM(0,05,&eplot_mi[1],(plot_it+1),FLAGS|VV,1<<1,0), /* Depth */
  1051. X    ITEM(1,15,NULL        ,(plot_it+1),FLAGS|Vx,1<<0,0), /* Z */
  1052. X};
  1053. X
  1054. X/*
  1055. X *  (C) menu
  1056. X */
  1057. X
  1058. X#undef    MLEFT
  1059. X#define MLEFT    0
  1060. X#undef    MWIDTH
  1061. X#define MWIDTH    15*8
  1062. X
  1063. Xstruct MenuItem c_mi[] = {
  1064. X    ITEM(0,00,NULL,c_it,FLAGS,0,0), /* About Mandel... */
  1065. X};
  1066. X
  1067. X/*
  1068. X *  Project menu
  1069. X */
  1070. X
  1071. X#undef    MWIDTH
  1072. X#define MWIDTH    9*8+COMMWIDTH
  1073. X
  1074. Xstruct MenuItem project_mi[] = {
  1075. X    SITEM(0,00,&project_mi[1],project_it,FLAGS   ,0,0,new_mi), /* new */
  1076. X     ITEM(1,10,&project_mi[2],project_it,FLAGS|Ax,0,'O'     ), /* open... */
  1077. X     ITEM(2,20,&project_mi[3],project_it,FLAGS|Ax,0,'S'     ), /* save */
  1078. X     ITEM(3,30,&project_mi[4],project_it,FLAGS   ,0,0       ), /* save as... */
  1079. X     ITEM(4,45,&project_mi[5],project_it,FLAGS   ,0,0       ), /* stop */
  1080. X     ITEM(5,55,NULL          ,project_it,FLAGS|Ax,0,'Q'     ), /* quit */
  1081. X};
  1082. X
  1083. X/*
  1084. X *  Options menu
  1085. X */
  1086. X
  1087. X#undef    MWIDTH
  1088. X#define MWIDTH 12*8+2
  1089. X
  1090. Xstruct MenuItem opt_mi[] = {
  1091. X    SITEM(0,00,&opt_mi[1],opts_it,FLAGS,0,0,color_mi), /* colors */
  1092. X    SITEM(1,10,&opt_mi[2],opts_it,FLAGS,0,0,res_mi  ), /* resolution */
  1093. X     ITEM(2,20,&opt_mi[3],opts_it,FLAGS,0,0         ), /* parameters */
  1094. X    SITEM(3,30,NULL      ,opts_it,FLAGS,0,0,pri_mi  ), /* priority */
  1095. X};
  1096. X
  1097. X
  1098. X/*
  1099. X *  Draw Menu
  1100. X */
  1101. X
  1102. X#undef    MWIDTH
  1103. X#define MWIDTH    (7*8)
  1104. X#undef    MLEFT
  1105. X#define MLEFT    -MWIDTH+40
  1106. X
  1107. Xstruct MenuItem draw_mi[] = {
  1108. X    SITEM(0,00,&draw_mi[1],draw_it,FLAGS,0,0,fun_mi  ), /* func */
  1109. X    SITEM(1,10,&draw_mi[2],draw_it,FLAGS,0,0,iplot_mi), /* iplot */
  1110. X    SITEM(2,20,NULL       ,draw_it,FLAGS,0,0,eplot_mi), /* eplot */
  1111. X};
  1112. X
  1113. X
  1114. X/*
  1115. X *  Batch Menu
  1116. X */
  1117. X
  1118. X#undef    MWIDTH
  1119. X#define MWIDTH    (8*8)
  1120. X#undef    MLEFT
  1121. X#define MLEFT    -MWIDTH+43
  1122. X
  1123. Xstruct MenuItem batch_mi[] = {
  1124. X    ITEM(0,00,&batch_mi[1],batch_it,FLAGS,     0,0), /* file */
  1125. X    ITEM(1,10,&batch_mi[2],batch_it,(FLAGS)-EN,0,0), /* wait */
  1126. X    ITEM(2,20,&batch_mi[3],batch_it,(FLAGS)-EN,0,0), /* continue */
  1127. X    ITEM(3,30,NULL        ,batch_it,(FLAGS)-EN,0,0), /* abort */
  1128. X};
  1129. X
  1130. X/*
  1131. X *  Main MenuStrip structure
  1132. X */
  1133. X
  1134. Xstruct Menu MandelMenu[] = {
  1135. X    { &MandelMenu[1],    2,0,21,10, MENUENABLED, " \xA9",    c_mi       },
  1136. X    { &MandelMenu[2],  30,0,59,10, MENUENABLED, "Project",  project_mi },
  1137. X    { &MandelMenu[3], 100,0,59,10, MENUENABLED, "Options",  opt_mi     },
  1138. X    { &MandelMenu[4], 170,0,37,10, MENUENABLED, "Draw",     draw_mi    },
  1139. X    { NULL,          220,0,43,10, MENUENABLED, "Batch",    batch_mi   },
  1140. X};
  1141. SHAR_EOF
  1142. echo "extracting MinRexx.c"
  1143. sed 's/^X//' << \SHAR_EOF > MinRexx.c
  1144. X/*
  1145. X *   This is an example of how REXX messages might be handled.    This is
  1146. X *   a `minimum' example that both accepts asynchronous REXX messages and
  1147. X *   can request REXX service.
  1148. X *
  1149. X *   Read this entire file!  It's short enough.
  1150. X *
  1151. X *   It is written in such a fashion that it can be attached to a program
  1152. X *   with a minimum of fuss.  The only external symbols it makes available
  1153. X *   are the seven functions and RexxSysBase.
  1154. X *
  1155. X *   This code is by Radical Eye Software, but it is put in the public
  1156. X *   domain.  I would appreciate it if the following string was left in
  1157. X *   both as a version check and as thanks from you for the use of this
  1158. X *   code.
  1159. X *
  1160. X *   If you modify this file for your own use, don't bump the version
  1161. X *   number; add a suffix, such as 1.0a or 1.0.3 or something, so we
  1162. X *   don't have fake `versions' floating around.
  1163. X *
  1164. X *   I [Olaf Seibert] changed it a bit for Mandel, that has its own
  1165. X *   kind of association list and command dispatcher. And I adjusted some
  1166. X *   comments to match the code.
  1167. X */
  1168. Xstatic char *blurb = "Radical Eye MinRexx 0.4 for Mandel" ;
  1169. X/*
  1170. X *   We read in our own personal little include.
  1171. X */
  1172. X#include "minrexx.h"
  1173. X/*
  1174. X *   All of our local globals, hidden from sight.
  1175. X */
  1176. Xstatic struct MsgPort *rexxPort ;       /* this is *our* rexx port */
  1177. Xstatic int bringerdown ;           /* are we trying to shut down? */
  1178. Xstatic struct rexxCommandList *globalrcl ; /* our command association list */
  1179. Xstatic long stillNeedReplies ;           /* how many replies are pending? */
  1180. Xstatic long rexxPortBit ;           /* what bit to wait on for Rexx? */
  1181. Xstatic char *extension ;           /* the extension for macros */
  1182. Xstatic int (*userdisp)() ;                 /* the user's dispatch function */
  1183. Xstruct RexxMsg *oRexxMsg ;           /* the outstanding Rexx message */
  1184. X/*
  1185. X *   Our library base.    Don't you dare close this!
  1186. X */
  1187. Xstruct RxsLib *RexxSysBase ;
  1188. X/*
  1189. X *   This is the main entry point into this code.
  1190. X */
  1191. Xlong upRexxPort(s, rcl, exten, uf)
  1192. X/*
  1193. X *   The first argument is the name of your port to be registered;
  1194. X *   this will be used, for instance, with the `address' command of ARexx.
  1195. X */
  1196. Xchar *s ;
  1197. X/*
  1198. X *   The second argument is an association list of command-name/user-data
  1199. X *   pairs.  It's an array of struct rexxCommandList, terminated by a
  1200. X *   structure with a NULL in the name field. The commands are case
  1201. X *   sensitive.  The user-data field can contain anything appropriate,
  1202. X *   perhaps a function to call or some other data.
  1203. X */
  1204. Xstruct rexxCommandList *rcl ;
  1205. X/*
  1206. X *   The third argument is the file extension for ARexx macros invoked
  1207. X *   by this program.  If you supply this argument, any `primitive' not
  1208. X *   in the association list rcl will be sent out to ARexx for
  1209. X *   interpretation, thus allowing macro programs to work just like
  1210. X *   primitives.  If you do not want this behavior, supply a `NULL'
  1211. X *   here, and those commands not understood will be replied with an
  1212. X *   error value of RXERRORNOCMD.
  1213. X */
  1214. Xchar *exten ;
  1215. X/*
  1216. X *   The fourth argument is the user dispatch function.  This function
  1217. X *   will *only* be called from dispRexxPort(), either from the user calling
  1218. X *   this function directly, or from dnRexxPort().  Anytime a command
  1219. X *   match is found in the association list, this user-supplied function
  1220. X *   will be called with three arguments---the Rexx message that was
  1221. X *   received, a pointer to the association pair, and a pointer to the
  1222. X *   command string.
  1223. X *   Note that the user function should never ReplyMsg() the message;
  1224. X *   instead he should indicate the return values with replyRexxCmd();
  1225. X *   otherwise we lose track of the messages that still lack replies.
  1226. X */
  1227. Xint (*uf)() ;
  1228. X/*
  1229. X *   upRexxPort() returns the signal bit to wait on for Rexx messages.
  1230. X *   If something goes wrong, it simply returns a `0'.  Note that this
  1231. X *   function is safe to call multiple times because we check to make
  1232. X *   sure we haven't opened already.  It's also a quick way to change
  1233. X *   the association list or dispatch function.
  1234. X */
  1235. X{
  1236. X   struct MsgPort *FindPort() ;
  1237. X   struct MsgPort *CreatePort() ;
  1238. X
  1239. X/*
  1240. X *   Some basic error checking.
  1241. X */
  1242. X /*
  1243. X   if (rcl == NULL || uf == NULL)
  1244. X      return(0L) ;
  1245. X  */
  1246. X/*
  1247. X *   If we aren't open, we make sure no one else has opened a port with
  1248. X *   this name already.  If that works, and the createport succeeds, we
  1249. X *   fill rexxPortBit with the value to return.
  1250. X *
  1251. X *   Note that rexxPortBit will be 0 iff rexxPort is NULL, so the check
  1252. X *   for rexxPort == NULL also insures that our rexxPortBit is 0.
  1253. X */
  1254. X   if (rexxPort == NULL) {
  1255. X      Forbid() ;
  1256. X      if (FindPort(s)==NULL)
  1257. X     rexxPort = CreatePort(s, 0L) ;
  1258. X      Permit() ;
  1259. X      if (rexxPort != NULL)
  1260. X     rexxPortBit = 1L << rexxPort->mp_SigBit ;
  1261. X   }
  1262. X/*
  1263. X *   Squirrel away these values for our own internal access, and return
  1264. X *   the wait bit.
  1265. X */
  1266. X   globalrcl = rcl ;
  1267. X   extension = exten ;
  1268. X   userdisp = uf ;
  1269. X   return(rexxPortBit) ;
  1270. X}
  1271. X/*
  1272. X *   This function closes the rexx library, but only if it is open
  1273. X *   and we aren't expecting further replies from REXX.  It's
  1274. X *   *private*, but it doesn't have to be; it's pretty safe to
  1275. X *   call anytime.
  1276. X */
  1277. Xstatic void closeRexxLib() {
  1278. X   if (stillNeedReplies == 0 && RexxSysBase) {
  1279. X      CloseLibrary(RexxSysBase) ;
  1280. X      RexxSysBase = NULL ;
  1281. X   }
  1282. X}
  1283. X/*
  1284. X *   This function closes down the Rexx port.  It is always safe to
  1285. X *   call, and should *definitely* be made a part of your cleanup
  1286. X *   routine.  No arguments and no return.  It removes the Rexx port,
  1287. X *   replies to all of the messages and insures that we get replies
  1288. X *   to all the ones we sent out, closes the Rexx library, deletes the
  1289. X *   port, clears a few flags, and leaves.
  1290. X */
  1291. Xvoid dnRexxPort() {
  1292. X   if (rexxPort) {
  1293. X      RemPort(rexxPort) ;
  1294. X      bringerdown = 1 ;
  1295. X/*
  1296. X *   A message still hanging around?  We kill it off.
  1297. X */
  1298. X      if (oRexxMsg) {
  1299. X     oRexxMsg->rm_Result1 = RXERRORIMGONE ;
  1300. X     ReplyMsg(oRexxMsg) ;
  1301. X     oRexxMsg = NULL ;
  1302. X      }
  1303. X      while (stillNeedReplies) {
  1304. X     WaitPort(rexxPort) ;
  1305. X     dispRexxPort() ;
  1306. X      }
  1307. X      closeRexxLib() ;
  1308. X      DeletePort(rexxPort) ;
  1309. X      rexxPort = NULL ;
  1310. X   }
  1311. X   rexxPortBit = 0 ;
  1312. X}
  1313. X/*
  1314. X *   Here we dispatch any REXX messages that might be outstanding.
  1315. X *   This is the main routine for handling Rexx messages.
  1316. X *   This function is fast if no messages are outstanding, so it's
  1317. X *   pretty safe to call fairly often.
  1318. X *
  1319. X *   If we are bring the system down and flushing messages, we reply
  1320. X *   with a pretty serious return code RXERRORIMGONE.
  1321. X *
  1322. X *   No arguments, no returns.
  1323. X */
  1324. Xvoid dispRexxPort() {
  1325. X   register struct RexxMsg *GetMsg() ;
  1326. X   register struct RexxMsg *RexxMsg ;
  1327. X   register char *p ;
  1328. X   register int dontreply ;
  1329. X
  1330. X/*
  1331. X *   If there's no rexx port, we're out of here.
  1332. X */
  1333. X   if (rexxPort == NULL)
  1334. X      return ;
  1335. X/*
  1336. X *   Otherwise we have our normal loop on messages.
  1337. X */
  1338. X   while (RexxMsg = (struct RexxMsg *)GetMsg(rexxPort)) {
  1339. X/*
  1340. X *   If we have a reply to a message we sent, we look at the second
  1341. X *   argument.    If it's set, it's a function we are supposed to call
  1342. X *   so we call it.  Then, we kill the argstring and the message
  1343. X *   itself, decrement the outstanding count, and attempt to close
  1344. X *   down the Rexx library.  Note that this call only succeeds if
  1345. X *   there are no outstanding messages.  Also, it's pretty quick, so
  1346. X *   don't talk to me about efficiency.
  1347. X */
  1348. X      if (RexxMsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG) {
  1349. X     if (RexxMsg->rm_Args[1]) {
  1350. X        ((int (*)())(RexxMsg->rm_Args[1]))(RexxMsg) ;
  1351. X     }
  1352. X     DeleteArgstring(RexxMsg->rm_Args[0]) ;
  1353. X     DeleteRexxMsg(RexxMsg) ;
  1354. X     stillNeedReplies-- ;
  1355. X     closeRexxLib() ;
  1356. X/*
  1357. X *   The default case is we got a message and we need to check it for
  1358. X *   primitives.  We skip past any initial tabs or spaces and initialize
  1359. X *   the return code fields.
  1360. X */
  1361. X      } else {
  1362. X     p = (char *)RexxMsg->rm_Args[0] ;
  1363. X     while (*p > 0 && *p <= ' ')
  1364. X        p++ ;
  1365. X     RexxMsg->rm_Result1 = 0 ;
  1366. X     RexxMsg->rm_Result2 = 0 ;
  1367. X/*
  1368. X *   If somehow the reply is already done or postponed, `dontreply' is
  1369. X *   set.
  1370. X */
  1371. X     dontreply = 0 ;
  1372. X/*
  1373. X *   If the sky is falling, we just blow up and replymsg.
  1374. X */
  1375. X     if (bringerdown) {
  1376. X        RexxMsg->rm_Result1 = RXERRORIMGONE ;
  1377. X/*
  1378. X *   Otherwise we call ExecuteBatchCommand() to find and execute
  1379. X *   the command.
  1380. X */
  1381. X     } else {
  1382. X        int result;
  1383. X
  1384. X        oRexxMsg = RexxMsg ;
  1385. X        result = ExecuteBatchCommand(p);
  1386. X/*
  1387. X *   If we did get -1, we didn't understand the command.  In
  1388. X *   this case, if we were supplied an extension in upRexxPort, we know
  1389. X *   that we should send the command out, so we do so, synchronously.
  1390. X *   The synchronous send takes care of our reply.  If we were given a
  1391. X *   NULL extension, we bitch that the command didn't make sense to us.
  1392. X */
  1393. X        if (result == -1) {
  1394. X           if (extension) {
  1395. X          syncRexxCmd(RexxMsg->rm_Args[0], RexxMsg) ;
  1396. X          dontreply = 1 ;
  1397. X           } else {
  1398. X          RexxMsg->rm_Result1 = RXERRORNOCMD ;
  1399. X           }
  1400. X        } else if (result == 0) {   /* Command failed */
  1401. X           RexxMsg->rm_Result1 = 20;
  1402. X           RexxMsg->rm_Result2 = 10;
  1403. X        }
  1404. X     }
  1405. X/*
  1406. X *   Finally, reply if appropriate.
  1407. X */
  1408. X     oRexxMsg = NULL ;
  1409. X     if (! dontreply)
  1410. X        ReplyMsg(RexxMsg) ;
  1411. X      }
  1412. X   }
  1413. X}
  1414. X/*
  1415. X *   Opens the Rexx library if unopened.  Returns success (1) or
  1416. X *   failure (0).  This is another function that is *private* but
  1417. X *   that doesn't have to be.
  1418. X */
  1419. Xstatic int openRexxLib() {
  1420. X   struct RxsLib *OpenLibrary() ;
  1421. X
  1422. X   if (RexxSysBase)
  1423. X      return(1) ;
  1424. X   return((RexxSysBase = OpenLibrary(RXSNAME, 0L)) != NULL) ;
  1425. X}
  1426. X/*
  1427. X *   This is the general ARexx command interface, but is not the one
  1428. X *   you will use most of the time; ones defined later are easier to
  1429. X *   understand and use.  But they all go through here.
  1430. X */
  1431. Xstruct RexxMsg *sendRexxCmd(s, f, p1, p2, p3)
  1432. Xchar *s ;
  1433. X/*
  1434. X *   The first parameter is the command to send to Rexx.
  1435. X */
  1436. Xint (*f)() ;
  1437. X/*
  1438. X *   The second parameter is either NULL, indicating that the command
  1439. X *   should execute asynchronously, or a function to be called when the
  1440. X *   message we build up and send out here finally returns.  Please note
  1441. X *   that the function supplied here could be called during cleanup after
  1442. X *   a fatal error, so make sure it is `safe'.  This function always is
  1443. X *   passed one argument, the RexxMsg that is being replied.
  1444. X */
  1445. XSTRPTR p1, p2, p3 ;
  1446. X/*
  1447. X *   These are up to three arguments to be stuffed into the RexxMsg we
  1448. X *   are building up, making the values available when the message is
  1449. X *   finally replied to.  The values are stuffed into Args[2]..Args[4].
  1450. X */
  1451. X{
  1452. X   struct RexxMsg *CreateRexxMsg() ;
  1453. X   STRPTR CreateArgstring() ;
  1454. X   register struct MsgPort *rexxport ;
  1455. X   register struct RexxMsg *RexxMsg ;
  1456. X
  1457. X/*
  1458. X *   If we have too many replies out there, we just return failure.
  1459. X *   Note that you should check the return code to make sure your
  1460. X *   message got out!  Then, we forbid, and make sure that:
  1461. X *    - we have a rexx port open
  1462. X *    - Rexx is out there
  1463. X *    - the library is open
  1464. X *    - we can create a message
  1465. X *    - we can create an argstring
  1466. X *
  1467. X *   If all of these succeed, we stuff a few values and send the
  1468. X *   message, permit, and return.
  1469. X */
  1470. X   if (rexxPort == NULL || stillNeedReplies > MAXRXOUTSTANDING-1)
  1471. X      return(NULL) ;
  1472. X   RexxMsg = NULL ;
  1473. X   if (openRexxLib() && (RexxMsg =
  1474. X         CreateRexxMsg(rexxPort, extension, rexxPort->mp_Node.ln_Name)) &&
  1475. X         (RexxMsg->rm_Args[0] = CreateArgstring(s, (long)strlen(s)))) {
  1476. X      RexxMsg->rm_Action = RXCOMM ;
  1477. X      RexxMsg->rm_Args[1] = (STRPTR)f ;
  1478. X      RexxMsg->rm_Args[2] = p1 ;
  1479. X      RexxMsg->rm_Args[3] = p2 ;
  1480. X      RexxMsg->rm_Args[4] = p3 ;
  1481. X      RexxMsg->rm_Node.mn_Node.ln_Name = RXSDIR ;
  1482. X      Forbid() ;
  1483. X      if (rexxport = FindPort(RXSDIR))
  1484. X     PutMsg(rexxport, RexxMsg) ;
  1485. X      Permit() ;
  1486. X      if (rexxport) {
  1487. X     stillNeedReplies++ ;
  1488. X     return(RexxMsg) ;
  1489. X      } else
  1490. X     DeleteArgstring(RexxMsg->rm_Args[0]) ;
  1491. X   }
  1492. X   if (RexxMsg)
  1493. X      DeleteRexxMsg(RexxMsg) ;
  1494. X   closeRexxLib() ;
  1495. X   return(NULL) ;
  1496. X}
  1497. X/*
  1498. X *   This function is used to send out an ARexx message and return
  1499. X *   immediately.  Its single parameter is the command to send.
  1500. X */
  1501. Xstruct RexxMsg *asyncRexxCmd(s)
  1502. Xchar *s ;
  1503. X{
  1504. X   return(sendRexxCmd(s, NULL, NULL, NULL, NULL)) ;
  1505. X}
  1506. X/*
  1507. X *   This function sets things up to reply to the message that caused
  1508. X *   it when we get a reply to the message we are sending out here.
  1509. X *   But first the function we pass in, which actually handles the reply.
  1510. X *   Note how we get the message from the Args[2]; Args[0] is the command,
  1511. X *   Args[1] is this function, and Args[2]..Args[4] are any parameters
  1512. X *   passed to sendRexxCmd() as p1..p3.  We pass the result codes right
  1513. X *   along.
  1514. X */
  1515. Xstatic void replytoit(msg)
  1516. Xregister struct RexxMsg *msg ;
  1517. X{
  1518. X   register struct RexxMsg *omsg ;
  1519. X
  1520. X   omsg = (struct RexxMsg *)(msg->rm_Args[2]) ;
  1521. X   replyRexxCmd(omsg, msg->rm_Result1, msg->rm_Result2, NULL) ;
  1522. X   ReplyMsg(omsg) ;
  1523. X}
  1524. X/*
  1525. X *   This function makes use of everything we've put together so far,
  1526. X *   and functions as a synchronous Rexx call; as soon as the macro
  1527. X *   invoked here returns, we reply to `msg', passing the return codes
  1528. X *   back.
  1529. X */
  1530. Xstruct RexxMsg *syncRexxCmd(s, msg)
  1531. Xchar *s ;
  1532. Xstruct RexxMsg *msg ;
  1533. X{
  1534. X   return(sendRexxCmd(s, (APTR)&replytoit, msg, NULL, NULL)) ;
  1535. X}
  1536. X/*
  1537. X *   There are times when you want to pass back return codes or a
  1538. X *   return string; call this function when you want to do that.
  1539. X */
  1540. Xvoid replyRexxCmd(msg, primary, secondary, string)
  1541. X/*
  1542. X *   The first parameter is the message we are replying to.
  1543. X */
  1544. Xregister struct RexxMsg *msg ;
  1545. X/*
  1546. X *   The next two parameters are the primary and secondary return
  1547. X *   codes.
  1548. X */
  1549. Xregister long primary, secondary ;
  1550. X/*
  1551. X *   The final parameter is a return string.  This string is only
  1552. X *   returned if the primary return code is 0, and a string was
  1553. X *   requested.
  1554. X */
  1555. Xregister char *string ;
  1556. X{
  1557. X   STRPTR CreateArgstring() ;
  1558. X
  1559. X/*
  1560. X *   Note how we make sure the Rexx Library is open before calling
  1561. X *   CreateArgstring . . . and we close it down at the end, if possible.
  1562. X */
  1563. X   if (primary == 0 && (msg->rm_Action & (1L << RXFB_RESULT))) {
  1564. X      if (string && openRexxLib())
  1565. X     secondary = (long)CreateArgstring(string, (long)strlen(string)) ;
  1566. X      else
  1567. X     secondary = 0L ;
  1568. X   }
  1569. X   msg->rm_Result1 = primary ;
  1570. X   msg->rm_Result2 = secondary ;
  1571. X   closeRexxLib() ;
  1572. X}
  1573. SHAR_EOF
  1574. echo "extracting Misc.c"
  1575. sed 's/^X//' << \SHAR_EOF > Misc.c
  1576. X/*
  1577. X * M A N D E L B R O T    C O N S T R U C T I O N   S E T
  1578. X *
  1579. X * (C) Copyright 1989 by Olaf Seibert.
  1580. X * Mandel may be freely distributed. See file 'doc/Notice' for details.
  1581. X *
  1582. X * Main Program, including some general routines
  1583. X */
  1584. X
  1585. X#include <exec/types.h>
  1586. X#include <intuition/intuition.h>
  1587. X#ifdef DEBUG
  1588. X#   include <stdio.h>
  1589. X#   undef STATIC
  1590. X#   define STATIC   /* EMPTY */
  1591. X#endif
  1592. X#include "mandel.h"
  1593. X
  1594. Xextern struct NewWindow XYNWindow;
  1595. Xextern struct Window *XYwindow;
  1596. X
  1597. X#define BORDERLEFT    3
  1598. X#define BORDERTOP    11
  1599. X#define BORDERBOTTOM    3
  1600. X
  1601. X#define CHARS        16    /* Change UpdateXYwindow also with this */
  1602. X
  1603. Xstruct NewWindow XYNWindow =
  1604. X{
  1605. X    2 * BORDERLEFT, 2 * BORDERTOP,
  1606. X    CHARS*8+BORDERLEFT*2, 2*8+BORDERTOP+BORDERBOTTOM,
  1607. X    2, 1,            /* DetailPen, BlockPen */
  1608. X    0,                /* CLOSEWINDOW */
  1609. X    WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | NOCAREREFRESH | SIMPLE_REFRESH,
  1610. X    NULL,            /* FirstGadget */
  1611. X    NULL,            /* default CheckMark */
  1612. X    (UBYTE *) "Re and Im",  /* Title */
  1613. X    NULL,            /* Screen */
  1614. X    NULL,            /* BitMap */
  1615. X    0, 0,            /* MinWidth, MinHeight */
  1616. X    0, 0,            /* MaxWidth, MaxHeight */
  1617. X    CUSTOMSCREEN        /* Screen type */
  1618. X};
  1619. X
  1620. Xdouble ReMouse, ImMouse;
  1621. X
  1622. X/*
  1623. X *  We always ask for INTUITICKS, since this window will only be open
  1624. X *  as long as we have the flashing lines.
  1625. X */
  1626. X
  1627. Xvoid OpenXYwindow()
  1628. X{
  1629. X    if (XYwindow == NULL) {
  1630. X    XYNWindow.Screen = MandelScreen;
  1631. X
  1632. X    if (XYwindow = OpenWindow(&XYNWindow)) {
  1633. X        XYwindow->UserPort = MainWindow->UserPort;
  1634. X        ModifyIDCMP(XYwindow, (long)CLOSEWINDOW | MOUSEBUTTONS | INTUITICKS);
  1635. X        SetDrMd(XYwindow->RPort, (long)JAM2);
  1636. X        SetAPen(XYwindow->RPort, (long)1);
  1637. X        SetBPen(XYwindow->RPort, (long)0);
  1638. X    }
  1639. X    }
  1640. X}
  1641. X
  1642. Xvoid CloseXYwindow()
  1643. X{
  1644. X    if (XYwindow) {
  1645. X    CloseWindowSafely(XYwindow);
  1646. X    XYwindow = NULL;
  1647. X    }
  1648. X}
  1649. X
  1650. Xvoid UpdateXYwindow(x, y)   /* corrected: 0..max */
  1651. Xint x, y;
  1652. X{
  1653. X    register int chars;
  1654. X    register struct RastPort *rp;
  1655. X    register long left, top;
  1656. X    char buffer[CHARS+2];    /* 1 extra for \0, and 1 for safety */
  1657. X    static char format[] = "%-16.10g";      /* 16 == CHARS */
  1658. X    /* -1.234567890e-99 is 16 chars with a precision of 10 digits */
  1659. X
  1660. X    ReMouse = LeftEdge + CXStep * x;
  1661. X    ImMouse = TopEdge - CYStep * y;
  1662. X
  1663. X    if (XYwindow) {
  1664. X    rp = XYwindow->RPort;
  1665. X    left = XYwindow->BorderLeft;
  1666. X    top = XYwindow->BorderTop;
  1667. X
  1668. X    chars = sprintf(buffer, format, ReMouse);
  1669. X    Move(rp, left, top+7);
  1670. X    Text(rp, buffer, (long)chars);
  1671. X
  1672. X    chars = sprintf(buffer, format, ImMouse);
  1673. X    Move(rp, left, top+15);
  1674. X    Text(rp, buffer, (long)chars);
  1675. X    }
  1676. X}
  1677. X
  1678. Xvoid MyExit(status)
  1679. Xchar *status;
  1680. X{
  1681. X    static char message[] = "\
  1682. X\0\144\25Mandelbrot Construction Set -- By KosmoSoft Productions\0a\
  1683. X\0\144\41                                  \0";
  1684. X/*    3^5^  10^    ^    20^    ^  30^     ^  40^    ^  50^  55^58^     */
  1685. X    register char *c=message+63;
  1686. X
  1687. X#ifdef AREXX
  1688. X    dnRexxPort();
  1689. X#endif
  1690. X
  1691. X    if (status) {
  1692. X    /* Center the message. */
  1693. X
  1694. X    {
  1695. X        register int halfway = 320 - (strlen(status) << 2);
  1696. X        message[60] = halfway >> 8; /* High byte */
  1697. X        message[61] = halfway;    /* Low byte */
  1698. X    }
  1699. X    while ((*(c++) = *(status++)) && c < message + 127);
  1700. X    *c = 0;
  1701. X
  1702. X    /* Let's be paranoid for a change... */
  1703. X    if (!IntuitionBase) IntuitionBase = (struct IntuitionBase *)
  1704. X        OpenLibrary ("intuition.library", 0L);
  1705. X    if (IntuitionBase)
  1706. X        DisplayAlert(RECOVERY_ALERT, message, 50L);
  1707. X    else {    /* AT_Recovery | AG_OpenLib | AO_Intuition */
  1708. X        CPTR AlertParameter = (CPTR) FindTask(NULL);
  1709. X        Alert(0x00038004L, &AlertParameter);
  1710. X    }
  1711. X
  1712. X    status=1;
  1713. X    }
  1714. X    CleanupDisplay((bool) TRUE);
  1715. X    if (DrawSigBit != -1) FreeSignal((long)DrawSigBit);
  1716. X    if (IntuitionBase) CloseLibrary(IntuitionBase);
  1717. X    if (LayersBase) CloseLibrary(LayersBase);
  1718. X    if (GfxBase) CloseLibrary(GfxBase);
  1719. X    exit ((int) (status != NULL));
  1720. X}
  1721. X
  1722. Xvoid _abort()
  1723. X{
  1724. X    MyExit("_abort() called...");
  1725. X}
  1726. X
  1727. Xbool Sure()
  1728. X{
  1729. X    bool Result;
  1730. X    ULONG OldIDCMP = MainWindow->IDCMPFlags;
  1731. X
  1732. X    static struct IntuiText Body[] =
  1733. X    {
  1734. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
  1735. X        25, 10, NULL, (UBYTE *) "You are going to", &Body[1]    },
  1736. X    {   MYFRONTPEN+1, AUTOBACKPEN, AUTODRAWMODE,
  1737. X        57, 25, &Topaz60, (UBYTE *) "destroy", &Body[2] },
  1738. X    {   MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
  1739. X        33, 40, NULL, (UBYTE *) "your picture !", NULL  }
  1740. X    };
  1741. X
  1742. X    if (Saved) return TRUE;
  1743. X
  1744. X    ModifyIDCMP(MainWindow, OldIDCMP &~ (MENUVERIFY | SIZEVERIFY | REQVERIFY));
  1745. X    Result = AutoRequest(MainWindow, &Body[0], &PositiveText, &NegativeText,
  1746. X    NULL, NULL, 200L, 90L);
  1747. X    ModifyIDCMP(MainWindow, OldIDCMP);
  1748. X
  1749. X    return Result;
  1750. X}
  1751. X
  1752. X/*
  1753. X * Render a requester in a window. If it won't fit, open a new window.
  1754. X * This new window will share the IDCMP port with the original
  1755. X * window. This is to save memory, signal bits and VERIFY deadlocks.
  1756. X * Returns the window in which the requester actually appears.
  1757. X */
  1758. X
  1759. Xstruct Window *MyRequest(request, window)
  1760. Xstruct Requester *request;
  1761. Xstruct Window *window;
  1762. X{
  1763. X    static struct NewWindow newwindow = {
  1764. X    0, 0, 0, 0, 2, 1,
  1765. X    NULL,        /* IDCMP flags -- port shared with main window */
  1766. X    WINDOWDEPTH | WINDOWDRAG | ACTIVATE | SIMPLE_REFRESH | NOCAREREFRESH,
  1767. X    NULL, NULL, NULL, NULL,
  1768. X    NULL, 0, 0, 0, 0, NULL    };
  1769. X    int width, height;
  1770. X    int borderleft, borderright, bordertop, borderbottom;
  1771. X    struct Window *oldwindow = window;
  1772. X
  1773. X    borderleft     = window->WScreen->WBorLeft;
  1774. X    borderright  = window->BorderRight;
  1775. X    bordertop     = window->WScreen->BarHeight + 1;
  1776. X    borderbottom = window->BorderBottom;
  1777. X
  1778. X    /* Center the requester in the given window.
  1779. X     * If impossible, open a new window to the place the requester in.
  1780. X     */
  1781. X
  1782. X     width = window->GZZWidth;
  1783. X     height = window->GZZHeight;
  1784. X
  1785. X     if (width < request->Width || height < request-> Height) {
  1786. X    /* Window too small. Open a new one */
  1787. X    newwindow.Screen = window->WScreen;
  1788. X    newwindow.Type = window->WScreen->Flags & SCREENTYPE;
  1789. X    newwindow.Title = window->Title;
  1790. X    newwindow.Width = request->Width + 2 * borderleft;
  1791. X    newwindow.Height = request->Height + bordertop + borderbottom;
  1792. X    newwindow.LeftEdge = (newwindow.Screen->Width - newwindow.Width) / 2;
  1793. X    newwindow.TopEdge = (newwindow.Screen->Height - newwindow.Height) / 2;
  1794. X
  1795. X    if (window = OpenWindow(&newwindow)) {
  1796. X        window->UserPort = oldwindow->UserPort;
  1797. X        /* Upen up the other port */
  1798. X        ModifyIDCMP(window, GADGETUP);
  1799. X    }
  1800. X
  1801. X    request->LeftEdge = borderleft;
  1802. X    request->TopEdge = bordertop;
  1803. X    } else {    /* The requester fits. Center it! */
  1804. X    request->LeftEdge = ((width - request->Width) >> 1);
  1805. X    request->TopEdge = ((height - request->Height) >> 1);
  1806. X    if (!(window->Flags & GIMMEZEROZERO)) {
  1807. X        request->LeftEdge += borderleft;
  1808. X        request->TopEdge += bordertop;
  1809. X    }
  1810. X    }
  1811. X
  1812. X    if (window && Request(request, window)) return window;
  1813. X
  1814. X    if (window) CloseWindowSafely(window);
  1815. X    return NULL;
  1816. X}
  1817. X
  1818. Xvoid EndMyRequest(request, window, original)
  1819. Xstruct Requester *request;
  1820. Xstruct Window *window, *original;
  1821. X{
  1822. X    EndRequest(request, window);
  1823. X    if (window != original) CloseWindowSafely(window);
  1824. X}
  1825. X
  1826. X/*
  1827. X * Wait on a request posted by MyRequest.
  1828. X * Returns when a gadget with GadgetID >= POSGADGETID is released,
  1829. X * so Gadgets with an ID < POSGADGETID will be ignored.
  1830. X * NEGGADID > POSGADID.
  1831. X * Any messages other than GADGETUP will be ignored.
  1832. X */
  1833. X
  1834. Xint WaitMyRequest(window)
  1835. Xstruct Window *window;
  1836. X{
  1837. X    int ID = 0;
  1838. X    struct IntuiMessage *message;
  1839. X    struct Gadget *Gadget;
  1840. X    ULONG Class;
  1841. X    ULONG OldIDCMP = window->IDCMPFlags;
  1842. X    ULONG SigMask;
  1843. X
  1844. X    if (!window)
  1845. X    return NEGGADGETID;
  1846. X
  1847. X    ModifyIDCMP(window, GADGETUP);
  1848. X
  1849. X#ifdef AREXX
  1850. X    SigMask = RexxMask | (1L << MainWindow->UserPort->mp_SigBit);
  1851. X#else
  1852. X    SigMask = (1L << MainWindow->UserPort->mp_SigBit);
  1853. X#endif
  1854. X
  1855. X    while (ID < POSGADGETID) {
  1856. X    Wait(SigMask);
  1857. X#ifdef AREXX
  1858. X    dispRexxPort();
  1859. X#endif
  1860. X    while (message = (struct IntuiMessage *) GetMsg(window->UserPort) ) {
  1861. X        Class = message->Class;
  1862. X        Gadget = (struct Gadget *)message->IAddress;
  1863. X        ReplyMsg(message);
  1864. X        if (Class != GADGETUP) continue;
  1865. X        ID = Gadget->GadgetID;
  1866. X        if (ID >= POSGADGETID) break; /* Also gets out of outer loop */
  1867. X    }
  1868. X    }
  1869. X    ModifyIDCMP(window, OldIDCMP);
  1870. X    return ID;
  1871. X}
  1872. X
  1873. Xvoid RectDraw(rp, x1, y1, x2, y2)
  1874. Xstruct RastPort *rp;
  1875. XSHORT x1, y1, x2,y2;
  1876. X{
  1877. X    Move(rp, (long) x1, (long) y1);
  1878. X    Draw(rp, (long) x2, (long) y1);
  1879. X    Draw(rp, (long) x2, (long) y2);
  1880. X    Draw(rp, (long) x1, (long) y2);
  1881. X    if (y2 > y1) y1++; else y1--;   /* Don't XOR the first pixel twice */
  1882. X    Draw(rp, (long) x1, (long) y1);
  1883. X}
  1884. X
  1885. Xvoid CrossDraw(rp, x, y, left, right, top, bottom)
  1886. Xstruct RastPort *rp;
  1887. XSHORT x, y, top, bottom, left, right;
  1888. X{
  1889. X    Move(rp, (long) left, (long) y);
  1890. X    Draw(rp, (long) right, (long) y);
  1891. X    Move(rp, (long) x, (long) top);
  1892. X    Draw(rp, (long) x, (long) bottom);
  1893. X}
  1894. X
  1895. Xvoid DisableSystemGadgets(gadget)
  1896. Xstruct Gadget *gadget;
  1897. X{
  1898. X    while (gadget) {
  1899. X    if (gadget->GadgetType & SYSGADGET) {
  1900. X        /* Ghost everything except the Title/Dragbar */
  1901. X        if ((gadget->GadgetType & 0x00F0) != WDRAGGING)
  1902. X        OffGadget(gadget, MainWindow, NULL);
  1903. X        gadget->Flags |= GADGDISABLED;
  1904. X    }
  1905. X    gadget = gadget->NextGadget;
  1906. X    }
  1907. X}
  1908. X
  1909. Xvoid EnableSystemGadgets(gadget)
  1910. Xstruct Gadget *gadget;
  1911. X{
  1912. X    USHORT Flags = 0;
  1913. X
  1914. X    while (gadget) {
  1915. X    if (gadget->GadgetType & SYSGADGET) {
  1916. X        Flags |= gadget->Flags;
  1917. X        gadget->Flags &= ~GADGDISABLED;
  1918. X    }
  1919. X    gadget = gadget->NextGadget;
  1920. X    }
  1921. X    /* Unghost everthing if necessary */
  1922. X    if (Flags & GADGDISABLED)   RefreshWindowFrame(MainWindow);
  1923. X}
  1924. X
  1925. Xvoid StopFraming()
  1926. X{
  1927. X    if (MainWindow) {
  1928. X    EnableSystemGadgets(MainWindow->FirstGadget);
  1929. X    ModifyIDCMP(MainWindow, MainWindow->IDCMPFlags & ~INTUITICKS);
  1930. X    }
  1931. X    MouseStatus = NOTFRAMING;
  1932. X    CloseXYwindow();
  1933. X}
  1934. X
  1935. Xvoid CheckMouse(Message)
  1936. Xregister struct IntuiMessage *Message;
  1937. X{
  1938. X    register SHORT top = MainWindow->BorderTop,
  1939. X           bottom = MainWindow->Height - MainWindow->BorderBottom - 1,
  1940. X           left = MainWindow->BorderLeft,
  1941. X           right = MainWindow->Width - MainWindow->BorderRight - 1;
  1942. X    static ULONG OldSecs, OldMicros;
  1943. X    static SHORT MidX, MidY;
  1944. X    USHORT MouseX, MouseY;
  1945. X
  1946. X    if (Message->IDCMPWindow == MainWindow) {
  1947. X    MouseX = Message->MouseX;
  1948. X    MouseY = Message->MouseY;
  1949. X    } else {
  1950. X    MouseX = MainWindow->MouseX;
  1951. X    MouseY = MainWindow->MouseY;
  1952. X    }
  1953. X
  1954. X    if (StillDrawing || MouseStatus != FLASHING &&
  1955. X    (MouseX < left || MouseX > right || MouseY < top || MouseY > bottom))
  1956. X    return;
  1957. X
  1958. X    MouseX -= left;
  1959. X    MouseY -= top;
  1960. X
  1961. X    if (Message->Class == MOUSEBUTTONS) {
  1962. X    if (Message->Code == SELECTDOWN) {
  1963. X        /* We selected a point */
  1964. X        switch (MouseStatus) {
  1965. X        case NOTFRAMING:
  1966. X        case FLASHING:
  1967. X        MouseStatus = NOPOINT;
  1968. X        DisableSystemGadgets(MainWindow->FirstGadget);
  1969. X        ModifyIDCMP(MainWindow, MainWindow->IDCMPFlags | INTUITICKS);
  1970. X        OpenXYwindow();
  1971. X        /* Now we can select our first corner */
  1972. X        break;
  1973. X        case NOPOINT:
  1974. X        FrameX1 = FrameX2 = MouseX;
  1975. X        FrameY1 = FrameY2 = MouseY;
  1976. X        MouseStatus = POINT1;
  1977. X        OldMicros = Message->Micros;
  1978. X        OldSecs = Message->Seconds;
  1979. X        /* We have the first point. Now go for the second */
  1980. X        break;
  1981. X        case POINT1:
  1982. X        if (DoubleClick(OldSecs, OldMicros,
  1983. X                Message->Seconds, Message->Micros)) {
  1984. X            /* Did we double-click? Then we have selected a center */
  1985. X            MouseStatus = CENTERFRAMING;
  1986. X            MidX = FrameX1;
  1987. X            MidY = FrameY1;
  1988. X            break;
  1989. X        }
  1990. X        FrameX2 = MouseX;
  1991. X        FrameY2 = MouseY;
  1992. X        /* Fall through to CENTERFRAMING */
  1993. X        case CENTERFRAMING:
  1994. X        if (FrameX1 == FrameX2 || FrameY1 == FrameY2) break;
  1995. X        EnableSystemGadgets(MainWindow->FirstGadget);
  1996. X        MouseStatus = FLASHING;
  1997. X        /* Point 1 should be upper left */
  1998. X        if (FrameX2 < FrameX1) {
  1999. X            /* I DO know I am reusing a variable here. Sorry! */
  2000. X            left=FrameX2; FrameX2=FrameX1; FrameX1=left;
  2001. X        }
  2002. X        if (FrameY2 < FrameY1) {
  2003. X            left=FrameY2; FrameY2=FrameY1; FrameY1=left;
  2004. X        }
  2005. X        break;
  2006. X        }    /* End switch MouseStatus */
  2007. X    }   /* End if Code == SELECTDOWN */
  2008. X    return;
  2009. X    }    /* End if Class == MOUSEBUTTONS */
  2010. X
  2011. X    /* We are moving the mouse. Show something! */
  2012. X
  2013. X    UpdateXYwindow(MouseX, MouseY);
  2014. X
  2015. X    SetDrMd(MainWindow->RPort, (ULONG) COMPLEMENT);
  2016. X
  2017. X    switch (MouseStatus) {
  2018. X    /* case NOTFRAMING: */
  2019. X    /*    return; */
  2020. X    case NOPOINT:
  2021. X    FrameX1 = FrameX2 = MouseX;
  2022. X    FrameY1 = FrameY2 = MouseY;
  2023. X    WaitTOF();
  2024. X    CrossDraw(MainWindow->RPort, FrameX1, FrameY1,
  2025. X            0, MainWindow->GZZWidth-1, 0, MainWindow->GZZHeight-1);
  2026. X    WaitTOF();
  2027. X    CrossDraw(MainWindow->RPort, FrameX1, FrameY1,
  2028. X            0, MainWindow->GZZWidth-1, 0, MainWindow->GZZHeight-1);
  2029. X    break;
  2030. X    case CENTERFRAMING:
  2031. X    FrameX1 = MouseX;
  2032. X    FrameY1 = MouseY;
  2033. X    FrameX2 = 2*MidX - FrameX1;
  2034. X    FrameY2 = 2*MidY - FrameY1;
  2035. X    skipto flashing;
  2036. X    case POINT1:
  2037. X    FrameX2 = MouseX;
  2038. X    FrameY2 = MouseY;
  2039. X    /* Deliberate Fall-Through to FLASHING */
  2040. X    case FLASHING:
  2041. Xflashing:
  2042. X    WaitTOF();
  2043. X    RectDraw(MainWindow->RPort, FrameX1, FrameY1, FrameX2, FrameY2);
  2044. X    WaitTOF();
  2045. X    RectDraw(MainWindow->RPort, FrameX1, FrameY1, FrameX2, FrameY2);
  2046. X    }
  2047. X}
  2048. X
  2049. Xvoid InitPenTable()
  2050. X{
  2051. X    register int i;
  2052. X
  2053. X    switch (PenTableMode) {
  2054. X    case MODULO:
  2055. X    PenTable[0] = 0;
  2056. X    for (i=1; i<MAXDEPTH; i++) PenTable[i] = 1 + i % (NumColors - 1);
  2057. X    break;
  2058. X    case RANGES:
  2059. X    PenTable[0] = 0;
  2060. X    for (i=1; i<MAXDEPTH; i++)
  2061. X        PenTable[i] = 1 + (i/RangeWidth) % (NumColors - 1);
  2062. X    case SELECT:
  2063. X    /* Don't change the table if it is user-defined */
  2064. X    break;
  2065. X    }
  2066. X}
  2067. X
  2068. Xvoid SelectMenu(MenuNum, CheckIt)
  2069. XLONG MenuNum;
  2070. Xbool CheckIt;
  2071. X{
  2072. X    struct MenuItem *Item = ItemAddress(MandelMenu, MenuNum);
  2073. X
  2074. X    ClearMenuStrip(MainWindow);
  2075. X
  2076. X    if (CheckIt)
  2077. X    Item->Flags |= CHECKED;
  2078. X    else
  2079. X    Item->Flags &= ~CHECKED;
  2080. X
  2081. X    SetMenuStrip(MainWindow, MandelMenu);
  2082. X}
  2083. X
  2084. Xvoid MakeMAND(mand)
  2085. Xstruct Mand *mand;
  2086. X{
  2087. X    int i;
  2088. X
  2089. X    mand->MandID = MAND;
  2090. X    mand->Size = sizeof(struct Mand) - 2 * sizeof(LONG);
  2091. X    mand->MaxDepth = MaxDepth;
  2092. X    mand->RangeWidth = RangeWidth;
  2093. X
  2094. X    mand->RainDist = RainbowDistance;
  2095. X    mand->RainRMax = RainbowRMax;
  2096. X    mand->RainGMax = RainbowGMax;
  2097. X    mand->RainBMax = RainbowBMax;
  2098. X
  2099. X    for (i=0; i < sizeof(mand->Coords); i++)
  2100. X    mand->Coords[i] = '\0';
  2101. X    sprintf(&mand->Coords[0], "%1.10g %1.10g %1.10g %1.10g",
  2102. X    LeftEdge, RightEdge, TopEdge, BottomEdge);
  2103. X
  2104. X    mand->FunctionNr = FunctionNr;
  2105. X    mand->PenTableMode = PenTableMode;
  2106. X    mand->WBWidth = WBWidth;
  2107. X    mand->WBHeight = WBHeight;
  2108. X
  2109. X}
  2110. X
  2111. Xbool InterpretMAND(mand, ilbminfo)
  2112. Xstruct Mand *mand;
  2113. Xstruct ILBM_info *ilbminfo;
  2114. X{
  2115. X    double NewLeftEdge, NewRightEdge, NewTopEdge, NewBottomEdge;
  2116. X    double Ratio;
  2117. X
  2118. X    /* Perform some checks on correctness of the chunk */
  2119. X    if (mand->MandID != MAND ||
  2120. X     mand->Size > sizeof(struct Mand) - 2 * sizeof(LONG) ||
  2121. X      mand->MaxDepth > MAXDEPTH ||
  2122. X       mand->RangeWidth > MAXDEPTH)
  2123. X    return FALSE;
  2124. X
  2125. X    if (sscanf(&mand->Coords[0], "%lf %lf %lf %lf",
  2126. X    &NewLeftEdge, &NewRightEdge, &NewTopEdge, &NewBottomEdge) < 4)
  2127. X    return FALSE;
  2128. X
  2129. X    MaxDepth    = mand->MaxDepth;
  2130. X    RangeWidth    = mand->RangeWidth;
  2131. X
  2132. X    /* Compensate for different sized windows */
  2133. X
  2134. X    Ratio    = (double)MainWindow->GZZWidth / (double)ilbminfo->header.w;
  2135. X    LeftEdge    = NewLeftEdge;
  2136. X    if (Ratio != 1.0)
  2137. X    RightEdge = NewLeftEdge + Ratio * (NewRightEdge - NewLeftEdge);
  2138. X    else        /* avoid round-off when almost exactly 1.0000 */
  2139. X    RightEdge = NewRightEdge;
  2140. X
  2141. X    Ratio    = (double)MainWindow->GZZHeight / (double)ilbminfo->header.h;
  2142. X    TopEdge    = NewTopEdge;
  2143. X    if (Ratio != 1.0)
  2144. X    BottomEdge = NewTopEdge - Ratio * (NewTopEdge - NewBottomEdge);
  2145. X    else        /* avoid round-off when almost exactly 1.0000 */
  2146. X    BottomEdge = NewBottomEdge;
  2147. X
  2148. X    CalcCSteps();
  2149. X
  2150. X    RainbowDistance = mand->RainDist;
  2151. X    RainbowRMax = mand->RainRMax;
  2152. X    RainbowGMax = mand->RainGMax;
  2153. X    RainbowBMax = mand->RainBMax;
  2154. X
  2155. X    if (mand->Size > OFFSETOF(FunctionNr, Mand) - 2*sizeof(long)) {
  2156. X    SetDrawingFunction(mand->FunctionNr);
  2157. X    PenTableMode = mand->PenTableMode;
  2158. X    WBWidth = mand->WBWidth;
  2159. X    WBHeight = mand->WBHeight;
  2160. X    InitPenTable();
  2161. X    }
  2162. X
  2163. X    UpdateCheckmarks();
  2164. X
  2165. X    return TRUE;
  2166. X}
  2167. SHAR_EOF
  2168. echo "End of archive 3 (of 4)"
  2169. # if you want to concatenate archives, remove anything after this line
  2170. exit
  2171.